﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Atmk.WaterMeter.MIS.Commons;
using Atmk.WaterMeter.MIS.Commons.ExceptionEx;
using Atmk.WaterMeter.MIS.Commons.Expands;
using Atmk.WaterMeter.MIS.Commons.Interfaces.GateWay;
using Atmk.WaterMeter.MIS.Commons.Interfaces.Logic.CT_NBIoT;
using Atmk.WaterMeter.MIS.Commons.Utils;
using Atmk.WaterMeter.MIS.Commons.ViewModels.ReadMeter;
using Atmk.WaterMeter.MIS.Entities.Enums;
using Atmk.WaterMeter.MIS.Entities.Models;
using Atmk.WaterMeter.MIS.GateWay.CT_NBIoT.ViewModel.GateWay;
using Atmk.WaterMeter.MIS.GateWay.CT_NBIoT.ViewModel.NaRespon;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NLog;

namespace Atmk.WaterMeter.MIS.Logic.CT_NBIoT
{
    /// <summary>
    /// 电信平台设备信息逻辑
    /// </summary>
    public class CT_PlatformDeviceInfoLogic : ICT_PlatformDeviceInfoLogic
    {
        private readonly ICT_NBIoT_CommandSenderHelper _ctNbioTCommandSenderHelper;
        private readonly Logger _logger = LogManager.GetCurrentClassLogger();

        public CT_PlatformDeviceInfoLogic(ICT_NBIoT_CommandSenderHelper ctNbioTCommandSenderHelper)
        {
            _ctNbioTCommandSenderHelper = ctNbioTCommandSenderHelper;
        }

        /// <summary>
        /// 获取指定设备的读数信息
        /// </summary>
        /// <param name="deviceId"></param>
        /// <returns></returns>
        public async Task<MeterReadingRecord> ReadFirstMeterRecord(string deviceId)
        {
            //获取当前时间抄表数据
            var res = _ctNbioTCommandSenderHelper.ReadDataHistory(deviceId);
            if (res.Count <= 0) throw new CB_NB_IoT_Exception("获取不到该水表数据");
            var readMeter = res.Where(r => r.GetTime.Date == DateTime.Now.Date).OrderByDescending(r => r.GetTime)
                .First();
            //水表读数
            var byteRead = Base64Convert.ConvertBytes(readMeter.Data.current);
            var reading = BytesConvert.BitConvertInts(byteRead, 6).First() / 100.00;
            var historys = Base64Convert.FrozensDatasBase64ConvertDouble(readMeter.Data.history, FrozenType.Hour)
                .Select(f => f.ToString(CultureInfo.InvariantCulture)).ToArray();
            var record = new MeterReadingRecord
            {
                //Number = "",
                ReadTime = readMeter.GetTime,
                Value = reading,
                //LastValue = 0,
                ValveState = readMeter.Data.valve == 1 ? (int)ValveState.Opening : (int)ValveState.Closed,
                Voltage = readMeter.Data.voltageTrue.ToString("f2"),
                    //((readMeter.Data.voltage + 100) * 0.01).ToString(CultureInfo.InvariantCulture),
                //CloseState = (int)CloseState.UnCLose,
                //Memo = string.Join(",", historys)
            };
            return await Task.Run(() => record);
        }

        /// <summary>
        /// 发送开关阀指令，并返回指令Id
        /// </summary>
        /// <param name="deviceId"></param>
        /// <param name="valveState"></param>
        /// <returns></returns>
        public async Task<BooleanResult> SetValveState(string deviceId, ValveState valveState)
        {
            var result = new BooleanResult {Success = false};
            var valve = valveState == ValveState.Opening ? 1 : 0;
            try
            {
                var res = _ctNbioTCommandSenderHelper.SendTapCommand(deviceId, valve);
                result.Message = res.commandId;
                result.ResJObject = JObject.FromObject(res);
                if (result.Message.Length > 0)
                    result.Success = true;
            }
            catch (Exception e)
            {
                result.ErrorMessage = e.Message;
            }
            return await Task.Run(() => result);
        }

        /// <summary>
        /// 获取冻结数据集合
        /// </summary>
        /// <param name="deviceId"></param>
        /// <param name="freezingType"></param>
        /// <returns></returns>
        public async Task<List<MeterFreezData>> ReadFreezData(string deviceId, int freezingType)
        {
            //获取当前时间抄表数据
            var res = _ctNbioTCommandSenderHelper.ReadFreezDatasHistory(deviceId)
                .Where(f => f.freezetype == freezingType);
            var result = res.Select(f => f.ToMeterFreezData()).ToList();
            return await Task.Run(() => result);
        }

        /// <summary>
        /// 获取最新冻结数据
        /// </summary>
        /// <param name="deviceId"></param>
        /// <param name="freezingType"></param>
        /// <returns></returns>
        public async Task<MeterFreezData> ReadNewFreezData(string deviceId, int freezingType)
        {
            //获取当前时间抄表数据
            var res = _ctNbioTCommandSenderHelper.ReadFreezDatasHistory(deviceId)
                .Where(f => f.freezetype == freezingType);
            var result = res.Select(f => f.ToMeterFreezData()).OrderByDescending(f=>f.timerecord).FirstOrDefault();
            return await Task.Run(() => result);
        }

        /// <summary>
        /// 发送查询冻结数据指令
        /// </summary>
        /// <param name="deviceId"></param>
        /// <param name="freezingType"></param>
        /// <returns></returns>
        public async Task<BooleanResult> SetFreezingDataCommand(string deviceId, int freezingType)
        {
            var result = new BooleanResult { Success = false };
            Enum.TryParse<FrozenType>(freezingType.ToString(), out var frozenType);
            try
            {
                DeviceCommandResp res = _ctNbioTCommandSenderHelper.SendFreezingCommand(deviceId, frozenType);
                result.Message = res.commandId;
                result.ResJObject = JObject.FromObject(res);
                if (result.Message.Length > 0)
                    result.Success = true;
            }
            catch (Exception e)
            {
                result.ErrorMessage = e.Message;
            }
            return await Task.Run(() => result);
        }

        /// <summary>
        ///  批量 发送开阀指令，并返回指令Id
        /// </summary>
        /// <param name="deviceId"></param>
        /// <param name="valveState"></param>
        /// <returns></returns>
        public async Task<BooleanResult> BatchOpenValve(string[] deviceIds)
        {
            var result = new BooleanResult { Success = false };
            try
            {
                var res = _ctNbioTCommandSenderHelper.batchTapCommand(deviceIds);
                result.Message = res.Result;
                result.ResJObject = JObject.FromObject(res);
                if (result.Message.Length > 0)
                    result.Success = true;
            }
            catch (Exception e)
            {
                result.ErrorMessage = e.Message;
            }
            return await Task.Run(() => result);
        }
    }
}